package com.sqlcheck.service.impl;

import com.sqlcheck.enums.GitPlatform;
import com.sqlcheck.service.TemporaryCredentialService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 临时凭据管理服务实现
 * 使用内存存储，不做持久化
 */
@Slf4j
@Service
public class TemporaryCredentialServiceImpl implements TemporaryCredentialService {
    
    // Git Token存储，key格式: taskId:platform
    private final Map<String, CredentialEntry> gitTokenStore = new ConcurrentHashMap<>();
    
    // 数据库密码存储，key格式: taskId
    private final Map<Long, CredentialEntry> databasePasswordStore = new ConcurrentHashMap<>();
    
    @Override
    public void storeGitToken(Long taskId, GitPlatform platform, String token, int expirationMinutes) {
        String key = buildGitTokenKey(taskId, platform);
        LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(expirationMinutes);
        
        gitTokenStore.put(key, new CredentialEntry(token, expirationTime));
        
        log.info("存储临时Git Token: taskId={}, platform={}, 过期时间={}", 
                taskId, platform, expirationTime);
    }
    
    @Override
    public String getGitToken(Long taskId, GitPlatform platform) {
        String key = buildGitTokenKey(taskId, platform);
        CredentialEntry entry = gitTokenStore.get(key);
        
        if (entry == null) {
            return null;
        }
        
        if (entry.isExpired()) {
            gitTokenStore.remove(key);
            log.info("Git Token已过期，自动清理: taskId={}, platform={}", taskId, platform);
            return null;
        }
        
        return entry.getCredential();
    }
    
    @Override
    public void storeDatabasePassword(Long taskId, String password, int expirationMinutes) {
        LocalDateTime expirationTime = LocalDateTime.now().plusMinutes(expirationMinutes);
        
        databasePasswordStore.put(taskId, new CredentialEntry(password, expirationTime));
        
        log.info("存储临时数据库密码: taskId={}, 过期时间={}", taskId, expirationTime);
    }
    
    @Override
    public String getDatabasePassword(Long taskId) {
        CredentialEntry entry = databasePasswordStore.get(taskId);
        
        if (entry == null) {
            return null;
        }
        
        if (entry.isExpired()) {
            databasePasswordStore.remove(taskId);
            log.info("数据库密码已过期，自动清理: taskId={}", taskId);
            return null;
        }
        
        return entry.getCredential();
    }
    
    @Override
    public void clearTaskCredentials(Long taskId) {
        // 清理Git Token
        gitTokenStore.entrySet().removeIf(entry -> {
            String key = entry.getKey();
            return key.startsWith(taskId + ":");
        });
        
        // 清理数据库密码
        databasePasswordStore.remove(taskId);
        
        log.info("清理任务相关凭据: taskId={}", taskId);
    }
    
    @Override
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void cleanupExpiredCredentials() {
        LocalDateTime now = LocalDateTime.now();
        
        // 清理过期的Git Token
        int removedGitTokens = 0;
        var gitIterator = gitTokenStore.entrySet().iterator();
        while (gitIterator.hasNext()) {
            var entry = gitIterator.next();
            if (entry.getValue().isExpired()) {
                gitIterator.remove();
                removedGitTokens++;
            }
        }
        
        // 清理过期的数据库密码
        int removedPasswords = 0;
        var dbIterator = databasePasswordStore.entrySet().iterator();
        while (dbIterator.hasNext()) {
            var entry = dbIterator.next();
            if (entry.getValue().isExpired()) {
                dbIterator.remove();
                removedPasswords++;
            }
        }
        
        if (removedGitTokens > 0 || removedPasswords > 0) {
            log.info("清理过期凭据: Git Token={}, 数据库密码={}", removedGitTokens, removedPasswords);
        }
    }
    
    @Override
    public boolean isGitTokenValid(Long taskId, GitPlatform platform) {
        String token = getGitToken(taskId, platform);
        return token != null && !token.trim().isEmpty();
    }
    
    @Override
    public boolean isDatabasePasswordValid(Long taskId) {
        String password = getDatabasePassword(taskId);
        return password != null && !password.trim().isEmpty();
    }
    
    private String buildGitTokenKey(Long taskId, GitPlatform platform) {
        return taskId + ":" + platform.name().toLowerCase();
    }
    
    /**
     * 凭据条目
     */
    private static class CredentialEntry {
        private final String credential;
        private final LocalDateTime expirationTime;
        
        public CredentialEntry(String credential, LocalDateTime expirationTime) {
            this.credential = credential;
            this.expirationTime = expirationTime;
        }
        
        public String getCredential() {
            return credential;
        }
        
        public boolean isExpired() {
            return LocalDateTime.now().isAfter(expirationTime);
        }
        
        public LocalDateTime getExpirationTime() {
            return expirationTime;
        }
    }
}